package com.bi.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.bi.common.Result;
import com.bi.entity.ChartComponent;
import com.bi.service.ChartComponentService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.List;
import java.util.Map;

/**
 * 图表组件控制器
 * 
 * @author BI Platform Team
 * @since 1.0.0
 */
@Slf4j
@RestController
@RequestMapping("/api/chart-components")
@RequiredArgsConstructor
@Tag(name = "图表组件管理", description = "图表组件的创建、配置、查询等功能")
public class ChartComponentController {

    private final ChartComponentService chartComponentService;

    @GetMapping
    @Operation(summary = "分页查询图表组件", description = "根据条件分页查询图表组件列表")
    public Result<IPage<ChartComponent>> getChartComponentPage(
            @Parameter(description = "当前页", example = "1") @RequestParam(defaultValue = "1") long current,
            @Parameter(description = "每页大小", example = "10") @RequestParam(defaultValue = "10") long size,
            @Parameter(description = "组件名称") @RequestParam(required = false) String name,
            @Parameter(description = "图表类型") @RequestParam(required = false) String chartType,
            @Parameter(description = "组件状态") @RequestParam(required = false) String status,
            @Parameter(description = "数据源类型") @RequestParam(required = false) String dataSourceType,
            @Parameter(description = "创建人") @RequestParam(required = false) String creator) {
        
        Map<String, Object> params = Map.of(
            "name", name != null ? name : "",
            "chartType", chartType != null ? chartType : "",
            "status", status != null ? status : "",
            "dataSourceType", dataSourceType != null ? dataSourceType : "",
            "creator", creator != null ? creator : ""
        );
        
        IPage<ChartComponent> page = chartComponentService.getChartComponentPage(current, size, params);
        return Result.success(page);
    }

    @GetMapping("/{id}")
    @Operation(summary = "获取图表组件详情", description = "根据ID获取图表组件的详细信息")
    public Result<ChartComponent> getChartComponentById(
            @Parameter(description = "组件ID") @PathVariable Long id) {
        
        ChartComponent chartComponent = chartComponentService.getById(id);
        if (chartComponent == null) {
            return Result.error("图表组件不存在");
        }
        return Result.success(chartComponent);
    }

    @PostMapping
    @Operation(summary = "创建图表组件", description = "创建新的图表组件")
    public Result<ChartComponent> createChartComponent(
            @Valid @RequestBody ChartComponent chartComponent) {
        
        try {
            // 设置创建人
            chartComponent.setCreator("current_user"); // 实际应从认证上下文获取
            
            boolean success = chartComponentService.createChartComponent(chartComponent);
            if (success) {
                return Result.success(chartComponent);
            } else {
                return Result.error("创建图表组件失败");
            }
        } catch (Exception e) {
            log.error("创建图表组件失败", e);
            return Result.error("创建图表组件失败: " + e.getMessage());
        }
    }

    @PutMapping("/{id}")
    @Operation(summary = "更新图表组件", description = "更新图表组件信息")
    public Result<ChartComponent> updateChartComponent(
            @Parameter(description = "组件ID") @PathVariable Long id,
            @Valid @RequestBody ChartComponent chartComponent) {
        
        try {
            chartComponent.setId(id);
            chartComponent.setUpdater("current_user"); // 实际应从认证上下文获取
            
            boolean success = chartComponentService.updateChartComponent(chartComponent);
            if (success) {
                return Result.success(chartComponent);
            } else {
                return Result.error("更新图表组件失败");
            }
        } catch (Exception e) {
            log.error("更新图表组件失败", e);
            return Result.error("更新图表组件失败: " + e.getMessage());
        }
    }

    @DeleteMapping("/{id}")
    @Operation(summary = "删除图表组件", description = "删除指定的图表组件")
    public Result<Void> deleteChartComponent(
            @Parameter(description = "组件ID") @PathVariable Long id) {
        
        try {
            boolean success = chartComponentService.deleteChartComponent(id);
            if (success) {
                return Result.success();
            } else {
                return Result.error("删除图表组件失败");
            }
        } catch (Exception e) {
            log.error("删除图表组件失败", e);
            return Result.error("删除图表组件失败: " + e.getMessage());
        }
    }

    @PostMapping("/{id}/test-datasource")
    @Operation(summary = "测试数据源连接", description = "测试图表组件的数据源连接是否正常")
    public Result<Map<String, Object>> testDataSource(
            @Parameter(description = "组件ID") @PathVariable Long id) {
        
        try {
            ChartComponent chartComponent = chartComponentService.getById(id);
            if (chartComponent == null) {
                return Result.error("图表组件不存在");
            }
            
            Map<String, Object> result = chartComponentService.testChartDataSource(chartComponent);
            return Result.success(result);
        } catch (Exception e) {
            log.error("测试数据源失败", e);
            return Result.error("测试数据源失败: " + e.getMessage());
        }
    }

    @PostMapping("/test-datasource")
    @Operation(summary = "测试数据源连接（预览）", description = "在保存前测试数据源连接")
    public Result<Map<String, Object>> previewTestDataSource(
            @Valid @RequestBody ChartComponent chartComponent) {
        
        try {
            Map<String, Object> result = chartComponentService.testChartDataSource(chartComponent);
            return Result.success(result);
        } catch (Exception e) {
            log.error("预览测试数据源失败", e);
            return Result.error("预览测试数据源失败: " + e.getMessage());
        }
    }

    @PostMapping("/{id}/data")
    @Operation(summary = "获取图表数据", description = "获取图表组件的数据")
    public Result<Map<String, Object>> getChartData(
            @Parameter(description = "组件ID") @PathVariable Long id,
            @RequestBody(required = false) Map<String, Object> params) {
        
        try {
            if (params == null) {
                params = Map.of();
            }
            
            Map<String, Object> result = chartComponentService.getChartData(id, params);
            return Result.success(result);
        } catch (Exception e) {
            log.error("获取图表数据失败", e);
            return Result.error("获取图表数据失败: " + e.getMessage());
        }
    }

    @PostMapping("/preview-data")
    @Operation(summary = "预览图表数据", description = "预览图表组件的数据结果")
    public Result<Map<String, Object>> previewChartData(
            @Valid @RequestBody PreviewChartRequest request) {
        
        try {
            Map<String, Object> params = request.getParams() != null ? request.getParams() : Map.of();
            Map<String, Object> result = chartComponentService.previewChartData(
                request.getChartComponent(), 
                params
            );
            return Result.success(result);
        } catch (Exception e) {
            log.error("预览图表数据失败", e);
            return Result.error("预览图表数据失败: " + e.getMessage());
        }
    }

    @PostMapping("/{id}/refresh-cache")
    @Operation(summary = "刷新图表缓存", description = "清除并刷新图表的缓存数据")
    public Result<Void> refreshCache(
            @Parameter(description = "组件ID") @PathVariable Long id) {
        
        try {
            boolean success = chartComponentService.refreshChartCache(id);
            if (success) {
                return Result.success();
            } else {
                return Result.error("刷新缓存失败");
            }
        } catch (Exception e) {
            log.error("刷新缓存失败", e);
            return Result.error("刷新缓存失败: " + e.getMessage());
        }
    }

    @PostMapping("/{id}/copy")
    @Operation(summary = "复制图表组件", description = "复制现有的图表组件")
    public Result<ChartComponent> copyChartComponent(
            @Parameter(description = "源组件ID") @PathVariable Long id,
            @RequestParam String newName) {
        
        try {
            ChartComponent newComponent = chartComponentService.copyChartComponent(id, newName);
            return Result.success(newComponent);
        } catch (Exception e) {
            log.error("复制图表组件失败", e);
            return Result.error("复制图表组件失败: " + e.getMessage());
        }
    }

    @GetMapping("/statistics")
    @Operation(summary = "获取图表组件统计信息", description = "获取图表组件的统计信息")
    public Result<Map<String, Object>> getChartStatistics() {
        try {
            Map<String, Object> statistics = chartComponentService.getChartStatistics();
            return Result.success(statistics);
        } catch (Exception e) {
            log.error("获取统计信息失败", e);
            return Result.error("获取统计信息失败: " + e.getMessage());
        }
    }

    @GetMapping("/chart-types/{chartType}")
    @Operation(summary = "按图表类型查询组件", description = "根据图表类型查询组件列表")
    public Result<List<ChartComponent>> getChartComponentsByType(
            @Parameter(description = "图表类型") @PathVariable String chartType) {
        
        try {
            List<ChartComponent> components = chartComponentService.getChartComponentsByType(chartType);
            return Result.success(components);
        } catch (Exception e) {
            log.error("按图表类型查询组件失败", e);
            return Result.error("按图表类型查询组件失败: " + e.getMessage());
        }
    }

    @PostMapping("/templates/{chartType}")
    @Operation(summary = "生成图表配置模板", description = "根据图表类型生成配置模板")
    public Result<Map<String, Object>> generateChartTemplate(
            @Parameter(description = "图表类型") @PathVariable String chartType,
            @RequestBody(required = false) Map<String, Object> dataConfig) {
        
        try {
            if (dataConfig == null) {
                dataConfig = Map.of();
            }
            
            Map<String, Object> template = chartComponentService.generateChartTemplate(chartType, dataConfig);
            return Result.success(template);
        } catch (Exception e) {
            log.error("生成图表模板失败", e);
            return Result.error("生成图表模板失败: " + e.getMessage());
        }
    }

    @PostMapping("/validate-config")
    @Operation(summary = "验证图表配置", description = "验证图表配置的有效性")
    public Result<Map<String, Object>> validateChartConfig(
            @RequestBody Map<String, Object> chartConfig) {
        
        try {
            Map<String, Object> result = chartComponentService.validateChartConfig(chartConfig);
            return Result.success(result);
        } catch (Exception e) {
            log.error("验证图表配置失败", e);
            return Result.error("验证图表配置失败: " + e.getMessage());
        }
    }

    @PostMapping("/{id}/export")
    @Operation(summary = "导出图表", description = "导出图表为指定格式")
    public Result<Map<String, Object>> exportChart(
            @Parameter(description = "组件ID") @PathVariable Long id,
            @RequestParam String format,
            @RequestBody(required = false) Map<String, Object> params) {
        
        try {
            if (params == null) {
                params = Map.of();
            }
            
            Map<String, Object> result = chartComponentService.exportChart(id, format, params);
            return Result.success(result);
        } catch (Exception e) {
            log.error("导出图表失败", e);
            return Result.error("导出图表失败: " + e.getMessage());
        }
    }

    @GetMapping("/popular-types")
    @Operation(summary = "获取热门图表类型", description = "获取使用频率最高的图表类型")
    public Result<List<Map<String, Object>>> getPopularChartTypes(
            @RequestParam(defaultValue = "10") Integer limit) {
        
        try {
            List<Map<String, Object>> popularTypes = chartComponentService.getPopularChartTypes(limit);
            return Result.success(popularTypes);
        } catch (Exception e) {
            log.error("获取热门图表类型失败", e);
            return Result.error("获取热门图表类型失败: " + e.getMessage());
        }
    }

    // 内部类定义请求对象

    public static class PreviewChartRequest {
        private ChartComponent chartComponent;
        private Map<String, Object> params;
        
        // getters and setters
        public ChartComponent getChartComponent() { return chartComponent; }
        public void setChartComponent(ChartComponent chartComponent) { this.chartComponent = chartComponent; }
        public Map<String, Object> getParams() { return params; }
        public void setParams(Map<String, Object> params) { this.params = params; }
    }
}